package com.xlhj.boot.service.impl;

import com.xlhj.boot.service.ScheduleService;
import lombok.SneakyThrows;
import org.quartz.Calendar;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.impl.calendar.AnnualCalendar;
import org.quartz.impl.calendar.CronCalendar;
import org.quartz.impl.calendar.DailyCalendar;
import org.quartz.impl.calendar.HolidayCalendar;
import org.quartz.impl.calendar.MonthlyCalendar;
import org.quartz.impl.calendar.WeeklyCalendar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.GregorianCalendar;

import static org.quartz.DateBuilder.newDate;

/**
 * @author: liucaijing
 * @description: ScheduleServiceImpl
 * @date: 2021/11/1 14:07
 */
@Service
public class ScheduleServiceImpl implements ScheduleService {

    @Autowired
    private Scheduler scheduler;

    @SneakyThrows
    @Override
    public void addSchedule(String jobName, String jobGroup, String jobClassName, String triggerName, String triggerGroup, String cronExpression) {
        try {
            scheduler.addCalendar("annuals", cronCalendar(), false, false);
            Class className = Class.forName(jobClassName);
            QuartzJobBean jobBean = (QuartzJobBean) className.newInstance();
            JobDetail jobDetail = JobBuilder.newJob(jobBean.getClass())
                    .withIdentity(jobName, jobGroup)
                    .storeDurably()
                    .build();
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().modifiedByCalendar("annuals")
                    .withIdentity(triggerName, triggerGroup)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                    .build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
            scheduler.start();
        } catch (SchedulerException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    private Calendar annualCalendar() {
        AnnualCalendar annualCalendar = new AnnualCalendar();
        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(newDate().inMonthOnDay(11, 5).build());
        annualCalendar.setDayExcluded(gregorianCalendar, true);
        return annualCalendar;
    }

    private Calendar cronCalendar() throws ParseException {
        CronCalendar cronCalendar = new CronCalendar("* 0-10,20-30 * * * ?");
        return cronCalendar;
    }

    private Calendar dailyCalendar() {
        DailyCalendar dailyCalendar = new DailyCalendar("08:00:00", "10:00:00");
        return dailyCalendar;
    }

    private Calendar holidayCalendar() {
        HolidayCalendar holidayCalendar = new HolidayCalendar();
        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(newDate().inMonthOnDay(11, 4).build());
        holidayCalendar.addExcludedDate(gregorianCalendar.getTime());
        return holidayCalendar;
    }

    private Calendar monthlyCalendar() {
        MonthlyCalendar monthlyCalendar = new MonthlyCalendar();
        monthlyCalendar.setDayExcluded(4, true);
        return monthlyCalendar;
    }

    private Calendar weeklyCalendar() {
        WeeklyCalendar weeklyCalendar = new WeeklyCalendar();
        weeklyCalendar.setDayExcluded(1, true);
        return weeklyCalendar;
    }
}
